/**
 * Copyright 2016- the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inmorn.orm.mybatis;

import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.session.Configuration;

import com.inmorn.context.beans.extend.InitializingBean;
import com.inmorn.context.beans.extend.RealityBean;

/**
 * @author Jeff.Li
 * @date 2016年11月10日
 * 注:扩展原mybatis-spring.jar
 */
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements InitializingBean,RealityBean<T>{

	private Class<T> mapperInterface;

	private boolean addToConfig = true;

	/**
	 * Sets the mapper interface of the MyBatis mapper
	 * 
	 * @param mapperInterface
	 *            class of the interface
	 */
	public void setMapperInterface(Class<T> mapperInterface) {
		this.mapperInterface = mapperInterface;
	}

	/**
	 * If addToConfig is false the mapper will not be added to MyBatis. This
	 * means it must have been included in mybatis-config.xml.
	 * <p>
	 * If it is true, the mapper will be added to MyBatis in the case it is not
	 * already registered.
	 * <p>
	 * By default addToCofig is true.
	 * 
	 * @param addToConfig
	 */
	public void setAddToConfig(boolean addToConfig) {
		this.addToConfig = addToConfig;
	}

	public void afterPropertiesSet() throws Exception {
		if(this.mapperInterface == null){
			throw new IllegalArgumentException("Property 'mapperInterface' is required");
		}

	    Configuration configuration = getSqlSession().getConfiguration();
	    if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
	      try {
	        configuration.addMapper(this.mapperInterface);
	      } catch (Throwable t) {
	        LOG.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", t);
	        throw new IllegalArgumentException(t);
	      } finally {
	        ErrorContext.instance().reset();
	      }
	    }
	}

	public T getObject() throws Exception {
		return getSqlSession().getMapper(this.mapperInterface);
	}
}
